package com.lemon.file.controller;

import cn.hutool.core.collection.CollUtil;
import com.lemon.common.core.domain.Result;
import com.lemon.common.core.web.controller.BaseController;
import com.lemon.common.core.web.domain.AjaxResult;
import com.lemon.common.core.web.page.TableDataInfo;
import com.lemon.common.log.annotation.Log;
import com.lemon.common.log.enums.BusinessType;
import com.lemon.common.security.annotation.RequiresPermissions;
import com.lemon.common.security.utils.ExcelUtil;
import com.lemon.file.domain.BiFileInfo;
import com.lemon.file.domain.vo.FolderVo;
import com.lemon.file.service.IBiFileInfoService;
import com.lemon.file.service.ISysFileService;
import com.lemon.system.api.domain.SysFile;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件请求处理
 * 
 * @author huangpeng
 */
@RestController
@RequestMapping(value = "file")
public class BiFileController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(BiFileController.class);

    @Autowired
    private ISysFileService sysFileService;

    @Autowired
    private IBiFileInfoService biFileInfoService;

    /**
     * 文件上传接口
     * @Title: upload
     * @Description: 文件上传接口
     * @param path 自定义的文件夹名，为空则随机生成
     * @param file 上传的文件
     * @param fileName 自定义的文件名，为空则随机生成
     * @return: R<SysFile>
     * @throws:
     * @author: huangpeng
     * @Date: 2022/6/5 22:09
     */
     // 暂时去掉权限 @RequiresPermissions("file:file:add")
    @ApiOperation(value = "文件上传", notes = "文件上传")
    @Log(title = "文件管理", businessType = BusinessType.INSERT)
    @PostMapping("upload")
    public Result<SysFile> upload(String path, @RequestParam("file") MultipartFile file, String fileName) {
        try {
            return Result.success(sysFileService.uploadFile(path, file, fileName), "文件上传成功");
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 前端文件上传接口
     * @Title: upload
     * @Description: 前端文件上传接口
     * @param path 自定义的文件夹名，为空则随机生成
     * @param file 上传的文件
     * @param fileName 自定义的文件名，为空则随机生成
     * @return: R<SysFile>
     * @throws:
     * @author: huangpeng
     * @Date: 2022/6/5 22:09
     */
    @ApiOperation(value = "文件上传", notes = "文件上传")
    @Log(title = "文件管理", businessType = BusinessType.INSERT)
    @PostMapping("uploadWeb")
    public Result<SysFile> uploadWeb(String path, @RequestParam("file") MultipartFile file, String fileName)
    {
        try
        {
            return Result.success(sysFileService.uploadFileWeb(path, file, fileName), "文件上传成功");
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取所有文件列表
     * @Title: listAll
     * @Description: 获取文件夹及文件夹下所有文件
     * @return: R<FolderVo>
     * @throws:
     * @author: huangpeng
     * @Date: 2022/6/5 22:23
     */
     // 暂时去掉权限  @RequiresPermissions("file:file:list")
    @ApiOperation(value = "获取文件夹及文件夹下所有文件", notes = "获取文件夹及文件夹下所有文件")
    @GetMapping(value = "listAll")
    public Result<FolderVo> listAll() {
        try {
            FolderVo folder = sysFileService.listAll();
            return Result.success(folder,"获取文件列表成功！");
        } catch (Exception e) {
            log.error("获取文件夹及文件夹下所有文件失败，errorMsg = {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 查询文件管理列表
     * @Title: list
     * @Description: 查询文件管理列表
     * @param biFileInfo
     * @return: TableDataInfo
     * @throws:
     * @author: huangpeng
     * @Date: 2022/12/24 20:44
     */
     // 暂时去掉权限 @RequiresPermissions("file:file:list")
    @GetMapping("list")
    public TableDataInfo list(BiFileInfo biFileInfo)
    {
        startPage();
        List<BiFileInfo> list = sysFileService.selectBiFileInfoList(biFileInfo);
        return getDataTable(list);
    }

    /**
     * 前端查询文件列表
     * @Title: listWed
     * @Description: 前端查询文件列表
     * @param biFileInfo
     * @return: TableDataInfo
     * @throws:
     * @author: huangpeng
     * @Date: 2023/9/13 19:13
     */
    @GetMapping("listWed")
    public TableDataInfo listWed(BiFileInfo biFileInfo)
    {
        startPage();
        List<BiFileInfo> list = sysFileService.listWed(biFileInfo);
        return getDataTable(list);
    }

    /**
     * 文件批量删除
     * @Title: deleteByBatch
     * @Description: 文件批量删除
     * @param filenameList 文件源文件名列表
     * @return: AjaxResult
     * @throws:
     * @author: huangpeng
     * @Date: 2022/6/5 22:30
     */
    @ApiOperation(value = "文件服务器文件删除（支持多个）", notes = "文件服务器文件删除")
    @RequiresPermissions("file:file:remove")
    @Log(title = "文件管理", businessType = BusinessType.DELETE)
    @DeleteMapping("deleteFileSourceByBatch")
    public AjaxResult deleteFileSourceByBatch(@RequestParam List<String> filenameList)  {
        try {
            return sysFileService.deleteSourceFileByBatch(filenameList) ? AjaxResult.success("删除成功") :
                    AjaxResult.error("删除文件失败");
        } catch (Exception e) {
            log.error("删除文件失败",e);
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 根据文件id列表删除文件
     * @Title: remove
     * @Description: 根据文件id列表删除文件
     * @param ids
     * @return: AjaxResult
     * @throws:
     * @author: huangpeng
     * @Date: 2022/12/25 12:11
     */
     // 暂时去掉权限,@RequiresPermissions("file:file:remove")
    @Log(title = "文件管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        try {
            // 获取源文件名
            List<BiFileInfo> fileInfoList = sysFileService.selectFileInfoByIds(ids);
            if (CollUtil.isNotEmpty(fileInfoList)) {
                // 带路径的不要文件后缀的文件名
                List<String> filenameList = fileInfoList.stream().
                        map(
                                model -> model.getFolder().replaceFirst("/", "") + "/" + model.getFileUrl().substring(model.getFileUrl().lastIndexOf("/") + 1))
                        .collect(Collectors.toList());
                if (sysFileService.deleteSourceFileByBatch(filenameList)) {
                    return toAjax(sysFileService.deleteBiFileInfoByIds(ids));
                }
            }
            return AjaxResult.error("文件删除失败");
        } catch (Exception e) {
            logger.error("文件删除失败，errorMsg = {}", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 文件下载
     * @Title: download
     * @Description: 文件下载
     * @param fileName
     * @param originFileName
     * @param response
     * @return: void
     * @throws:
     * @author: huangpeng
     * @Date: 2022/6/5 22:50
     */
    @RequiresPermissions("file:file:download")
    @GetMapping("download")
    public void download(@RequestParam("fileName") String fileName,
                         @RequestParam("originFileName") String originFileName, HttpServletResponse response)  {
        try {
            sysFileService.download(fileName, originFileName, response);
        } catch (Exception e) {
            log.error("下载文件失败，msg={}",e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 导出文件管理列表
     * @Title: export
     * @Description: 导出文件管理列表
     * @param response
     * @param biFileInfo
     * @return: void
     * @throws:
     * @author: huangpeng
     * @Date: 2022/12/25 11:36
     */
    @RequiresPermissions("file:file:export")
    @Log(title = "文件管理", businessType = BusinessType.EXPORT)
    @PostMapping("export")
    public void export(HttpServletResponse response, BiFileInfo biFileInfo)
    {
        List<BiFileInfo> list = sysFileService.selectBiFileInfoList(biFileInfo);
        ExcelUtil<BiFileInfo> util = new ExcelUtil<>(BiFileInfo.class);
        util.exportExcel(response, list, "文件管理数据");
    }

    /**
     * 通过文件url获取文件信息
     * @Title: getFileInfoByUrl
     * @Description: 通过文件url获取文件信息
     * @param fileUrl 文件url
     * @return: Result<BiFileInfo>
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/20 23:45
     */
    @GetMapping(value = "/getFileInfoByUrl")
    public Result<BiFileInfo> getFileInfoByUrl(@RequestParam(value = "fileUrl") String fileUrl) {
        return Result.success(biFileInfoService.getFileInfoByUrl(fileUrl));
    }

    /**
     * 通过文件url获取文件信息列表
     * @Title: getFileInfoByUrls
     * @Description: 通过文件url获取文件信息列表
     * @param fileUrls 文件url，多个逗号隔开
     * @return: Result<BiFileInfo>
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/20 23:45
     */
    @GetMapping(value = "/getFileInfoByUrls")
    public AjaxResult getFileInfoByUrls(@RequestParam(value = "fileUrls") String fileUrls) {
        return AjaxResult.success(biFileInfoService.getFileInfoByUrls(fileUrls));
    }
}